package com.mamingchao.concurrent.threads_communication3;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;

/**
 * 用Semaphore 可以实现，a线程先acquire,运行到第5个的时候，release；  然后在acquire,运行剩余的逻辑，然后再release
 * b一直acquire，acquire到之后执行业务逻辑，然后release
 *
 * 这种实现有两个问题
 * 1、必须让线程a先运行，a先acquire到
 * 2、a运行到第5个元素的时候，release后，不能立马acquire，要不然 a release完，里面又是a acquire到，b 根本没有机会
 *
 *   针对第二个问题，有人提出在线程a里 让b join进来，这个想法很棒
 *
 * Created by mamingchao on 2020/9/19.
 */
public class WithSemaphore {

    static Semaphore semaphore = new Semaphore(1);

    static List<Integer> lists = new ArrayList<>();

    public static void main(String[] args) {

        Thread b = new Thread( ()->{

            try {
                semaphore.acquire();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Thread b has receive the notification");

            semaphore.release();
        });


        Thread a = new Thread(() -> {
            try {
                semaphore.acquire();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            for (int i = 0; i < 10; i++) {
                lists.add(i);
                System.out.println(i);
                if (i == 5){
                    semaphore.release();



                    // 让线程b join 过来
                    try {
                        b.join();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    try {
                        semaphore.acquire();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

//                try {
//                    TimeUnit.SECONDS.sleep(1);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
            }
        });




        //必须保证 a先运行
        a.start();
        b.start();
    }

}
